/**
 * Copyright (c) 2016,http://www.365wuliu.com/  All Rights Reserved.
 */
package com.cargo.security;

import com.cargo.base.utils.CheckUtil;
import com.cargo.base.utils.CommonUtil;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * ShiroRealm:shiro控制类
 * 
 * @Project Name:cargo
 * @File Name:ShiroRealm.java
 * @Package Name:com.cargo.security
 * @Creator:wizard
 * @Date:2016年4月14日下午2:23:07
 */
public class ShiroRealm extends AuthorizingRealm {
	
	
	public ShiroRealm() {
		setAuthenticationTokenClass(UsernamePasswordToken.class);
	}

	/**
	 * Shiro登录认证方法
	 * 进行密码匹配
	 *  1 将前台穿过来的token 传入AuthenticatingRealm的getAuthenticationInfo方法中作为一个参数->token
	 *  2 将前台传过来的token 在这个方法中进行解密 然后再传入 AuthenticatingRealm的getAuthenticationInfo方法中作为一个参数->info
	 *  3 在AuthenticatingRealm的getAuthenticationInfo方法中 进行 前台两个参数 token 和 info 的匹配  匹配成功返回 info  匹配不成功 返回 异常
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {
		UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
		String usernamekey = new String(token.getUsername());
		String password = new String(token.getPassword());
		String usernamekey_shirouser = JWTUtils.decode(usernamekey);  //其实这个就是 之前登陆是 存入的 shirouser对象, 登陆的时候用 api_key加密了, 所以这里用api_key 来解密
		ShiroUser shiroUser = CommonUtil.jsonToObject(usernamekey_shirouser, ShiroUser.class);
		//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，与数据库中用户名和密码进行比对。比对成功则返回info，比对失败则抛出对应信息的异常
		return new SimpleAuthenticationInfo(shiroUser, password, getName());
	}

	/**
	 * Shiro赋权方法
	 * 1、从Shiro中获取登录用户信息
	 * 2、获得登录用户权限认证 列表
	 * 3、将从登录用户信息中获得的权限认证列表放入到SimpleAuthorizationInfo中
	 * 4、返回SimpleAuthorizationInfo
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		try {
			
			//从Shiro中获取登录用户信息
			ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
			//判断登录用户权限认证列表否为空，如果不为空则进入Shiro赋权逻辑
			if(CheckUtil.checkObj(shiroUser.getPermissions())){
				SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
				//设置权限认证列表  (这里其实还可以设置校角色,但是用不到,所以没设置)
				info.setStringPermissions(shiroUser.getPermissions());
				return info;
			}else{
				return null;
			}
		} catch (Exception e) {
			return null;
		}
	}
}
